﻿/**
	QListBox.get(id):获取下拉框对象。
 	可以使用以下方法对tip对象进行操作：
 	selectItem(array/-99/id):选中指定的id的下拉框列表项,可以传递一个数组，数组内容是ID，-99表示全选
 	rejectItem(array/-99/id):参数格式如上，功能为取消选中项
 	getSelectedItems():获取被选中项，返回值为数组,数组内容是对象,对象包括id和value属性,eg:[{id:1,value:1}....]
 	getAllItems():获取所有项，返回值如上描述
 	getValue():将getSelectedItems方法进行封装，只返回id数组
 	getText():将getSelectedItems方法进行封装，只返回value数组
 	setOrientation('down'/'up'):设置下拉框展示的位置，up:下拉框在显示框上面显示,down:下拉框在显示框下面显示
 	setGravity('left'/'center'/'right'):设置下拉框和显示框的对齐方式
 	setMultiSelect(true/false):设置是否可以多选
 	setAllButtonDisabled(true/false):设置全选按钮是否失效
 	refresh(array,itemType):配置数据源，array为数据源数组，数据源格式为数组，数组内容为包含id和value属性的对象,
 							itemType为下拉项类型
 	clearListBox():清空下拉框内容，返回原下拉框的DOM对象
 	clearTextBox():清空显示框内容，返回原显示框的DOM对象
 	
 	tip的层级说明：
 	一个tip包括一个textBox和一个listBox对象,tip,textBox,listBox含有body,style属性分别指向对应的DOM节点和DOM节点的样式
 	可以操作body或者style来更改样式,如:更改tip的整体宽度,tip.style.width = xxx;，更改listBox的宽度,tip.listBox.style.width=xxx
 */
/**
 * 创建QListBox命名空间
 */
(function QListBox(window, undefined){
	
	/**
	 * 保存window对象
	 */
	var document = window.document,
		_QListBox = window.QListBox,
		_$$ = window.$$,
		QListBox = {};
	
	window.QListBox = QListBox;
	
	/**
	 * 工具对象
	 */
	QListBox.Util = {};
	
	/**
	 * window原有对象的还原方法
	 */
	QListBox.noConflict = function(){
		window.QListBox = _QListBox;
	};
	
	/**
	 * 配置
	 */
	QListBox.option = {
		
		selectOne : true,
		"boxClass" : "QListBox",
		"textClass" : "QListBox_Text",
		"listClass" : "QListBox_OL",
		"itemClass" : "QListBox_LI"
	}
	
	/**
	 * 创建listbox的构造函数
	 */
	function listbox(_DOM, _option){
		
		var $DOM = _DOM || $("<div>"),
			option = $.extend(true, {}, QListBox.option),	// 深层复制配置
			items = [],
			selected = [],
			textbox,
			itembox,
			selected_Fn = function(){},
			default_selected_fn = function(){};
		
		if(_option) option = $.extend(true, option, _option);
		
		$DOM.addClass(option.boxClass);
		
		textbox = $("<div>").addClass(option.textClass).appendTo($DOM);
		
		itembox = $("<ol>").addClass(option.listClass).appendTo($DOM);
		
		this.getDOM = function(){
			return $DOM;
		}
		
		if(option.css){
			$DOM.css(option.css);
		}
		
		/*
		 * 设置text
		 */
		this.setText = function(_text){
			return textbox.html(_text);
		}
		
		this.getText = function(){
			return textbox.html();
		}
		
		this.getValue = function(){
			
			if(option.selectOne){
				return selected[0];
			}
			
			var list = [];
			for(var i=0, len=selected.length; i<len; i++){
				list.push(selected[i].value);
			}
			
			return list.join(",");
		}
		
		this.hide = function(){
			itembox.css("visibility","hidden");
		}
		
		this.clear = function(){
			textbox.html("");
			itembox.empty();
			items = selected = [];
			
			if(option.defaultItem){
				this.addItem(option.defaultItem);
				this.selectItem(option.defaultItem.value);
			}
		}
		
		this.selectItem = this.setValue = function(_value){
			
			if(option.selectOne){
				selected = [];
			}
			
			var item = this.getItem(_value);
			if(!item || item.disabled) return;
			
			selected[selected.length] = item.value;
			this.setText(item.text);
			selected_Fn(_value);
		}
		
		this.onSelected = function(_fn, _exec){
			
			var caller = this;
			//默认执行以下内容
			if(_exec != undefined && !_exec){
				
				selected_Fn = _fn;
				
			} else {
				
				selected_Fn = function(){
					default_selected_fn.apply(caller, arguments);
					_fn.apply(caller, arguments);
				};
			}
		}
		
		this.getSelectedItem = function(){
			
			var list = [];
			
			for(var i=0, len=items.length; i<len; i++){
			
				if(option.selectOne && items[i].value == selected[0]){
					 return items[i];
				}
				
				for(var j=0, len2=selected.length; j<len2; j++){
					
					if(items[i].value == selected[j]){
						list.push(items[i]);
						break;
					}
				}
			}
			
			return list;
		}
		
		this.getItem = function(_value){
			
			for(var i=0, len=items.length; i<len; i++){
				if(items[i].value == _value) return items[i];
			}
		}
		
		this.addItem = function(_obj){
			
			items[items.length] = _obj;
			var _text = _obj["text"],
				_value = _obj["value"],
				_type = _obj["type"],
				_disabled = _obj["disabled"],
				_class = _obj["class"];
			
			if(!_type || type == "a"){
			
				var tmpA = $("<a>").html(_text),
					tmpLi = $("<li>").addClass(option.itemClass).append(tmpA);
				tmpLi.appendTo(itembox);
				tmpLi.attr("value", _value);
				//tmpLi.attr("title", _text);//鼠标移上去有提示
				
				if(_class){
					tmpLi.addClass(_class);
				}
				
				if(!_disabled){
				
					tmpLi.bind("click", {obj: this, obj2: _value}, function(event){
						
						var listbox = event.data.obj;
						listbox.selectItem(event.data.obj2);
						listbox.hide();
						event.stopPropagation();
					});
				} else {
					
					tmpLi.addClass("disabled");
					//tmpLi.attr("title", "不可选");
					tmpLi.bind("click", {obj: this, obj2: _value}, function(event){
						
						event.stopPropagation();
					});
				}
			}
		}
		
		/*
		 * 事件处理
		 */
		$DOM.bind("click", {obj: itembox}, function(event){
			
			var _fn = window.document.onclick,
				$obj = event.data.obj,
				list = QListBox.List,
				status = $obj.css("visibility") != "hidden";
			
			for(var i=0, len=list.length; i<len; i++){
				list[i].hide();
			}

			status ?  $obj.css("visibility","hidden") : $obj.css("visibility","visible");
			
			window.document.onclick = function(){
				
				$obj.css("visibility","hidden");
				if(_fn) _fn.apply(window) ;
				window.document.onclick = _fn;
			}
			event.stopPropagation();
		});
		
		if(option.defaultItem){
			this.addItem(option.defaultItem);
			this.selectItem(option.defaultItem.value);
		}
	};
	
	listbox.prototype.refresh = function(_data){
		
		if(!_data || !$.isArray(_data)) return this;
		
		this.clear();
		
		for(var i=0, len=_data.length; i<len; i++){
			
			if(typeof _data[i] == "object"){
				this.addItem(_data[i]);
			} else {
				this.addItem({text: _data[i], value:_data[i]});
			}
		}
		
		return this;
	}
	
	
	QListBox.init = function(_pk, _option){
		
		var $DOM = $(_pk);							//传入对象可以是jquery对象，或者是表达式
		var box = new listbox($DOM, _option);
		QListBox.List[_pk] = QListBox.List.length;				//索引，其实没必要，直接用对象的map性质存储也是可以的，这里为了让代码更好理解
		QListBox.List.push(box);							//保存创建的对象
		return box;								//初始化完成，返回对象
	}
	
	/**
	 * 保存生成的listbox
	 */
	QListBox.List = [];
	
	/**
	 * 获取tip
	 */
	QListBox.get = function(_pk){
		
		return QListBox.List[QListBox.List[_pk]];
	}
})(window);